opc = [];
//discussion points
//1. I made every long takes two slots, is that OK?
//2. operation[1], I pushed a null into the stack
//3. float perhaps be wrong
//4. is it currentFrame.method.attributes[0].code[pc], or anything else?
//5. I did not use type information, is that OK?

//this is for the array object reference operations
ArrayObject = function(type,size) {
	this.type = type;
	this.size = size;
	this.array = [];
}

opc[0] = function nop() {};
//Not sure about [1], how to push a null into a stack
opc[1] = function aconst_null() { 
tmpNull = null;
currentFrame.operandStack.push(tmpNull);}

opc[2] = function iconst_m1() { currentFrame.operandStack.push(-1); };
opc[3] = function iconst_0() { currentFrame.operandStack.push(0); };
opc[4] = function iconst_1() { currentFrame.operandStack.push(1); };
opc[5] = function iconst_2() { currentFrame.operandStack.push(2); };
opc[6] = function iconst_3() { currentFrame.operandStack.push(3); };
opc[7] = function iconst_4() { currentFrame.operandStack.push(4); };
opc[8] = function iconst_5() { currentFrame.operandStack.push(5); };

opc[9] = function lconst_0() {  
currentFrame.operandStack.push(0);};
opc[10] = function lconst_0() { 
currentFrame.operandStack.push(1); };

opc[11] = function fconst_0() { 
currentFrame.operandStack.push(0.0); };
opc[12] = function fconst_1() { 
currentFrame.operandStack.push(1.0); };
opc[13] = function fconst_2() { 
currentFrame.operandStack.push(2.0); };

opc[14] = function dconst_0() { 
currentFrame.operandStack.push(0.0); };
opc[15] = function dconst_1() { 
currentFrame.operandStack.push(1.0); };

opc[16] = function bipush() { 
	pc++;
	tmpByte = currentFrame.method.attributes[0].code[pc];
	currentFrame.operandStack.push(tmpByte); 
};

opc[17] = function sipush() { 
	pc++;
	tmpShort = currentFrame.method.attributes[0].code[pc];
	currentFrame.operandStack.push(tmpShort); 
};

//Question: whether it is attributes[0], need it call other method to determine the index
opc[18] = function ldc() {
	pc++;
	index = currentFrame.method.attributes[0].code[pc];
	stringIndex = mainclass.constant_pool[index].string_index;
	returnString = getStringFromConstantId(stringIndex);
	currentFrame.operandStack.push(returnString);
 };
opc[19] = function ldc_w() {
	pc++;
	index1 = currentFrame.method.attributes[0].code[pc];
	pc++;
	index2 = currentFrame.method.attributes[0].code[pc];
	index = (index1 << 8) | index2;
	stringIndex = mainclass.constant_pool[index].string_index;
	returnString = getStringFromConstantId(stringIndex);
	currentFrame.operandStack.push(returnString);
 };

opc[20] = function ldc2_w() { 
	pc++;
	index1 = currentFrame.method.attributes[0].code[pc];
	pc++;
	index2 = currentFrame.method.attributes[0].code[pc];
	index = (index1 << 8) | index2;
	numHighByte = mainclass.constant_pool[index].high_bytes;
	numLowByte = mainclass.constant_pool[index].low_bytes;
	num = (numHighByte << 8) | numLowByte;
	currentFrame.operandStack.push(num);
	if(debugMode == 1) {
		alert("ldc2_w: index: " + index + "\n" + num + "\n" + "operandStack: "+currentFrame.operandStack.toString());
		
	}
};


opc[21] = function iload() { 
	pc++;
	index = currentFrame.method.attributes[0].code[pc];
	currentFrame.operandStack.push(currentFrame.localVariables[index]); 
};

opc[22] = function lload() {  
	pc++;
	index = currentFrame.method.attributes[0].code[pc];
	currentFrame.operandStack.push(currentFrame.localVariables[index]);
};

opc[23] = function fload() { 
	pc++;
	index = currentFrame.method.attributes[0].code[pc];
	currentFrame.operandStack.push(currentFrame.localVariables[index]);
};
opc[24] = function dload() { 
	pc++;
	index = currentFrame.method.attributes[0].code[pc];
	currentFrame.operandStack.push(currentFrame.localVariables[index]);
};
opc[25] = function aload() { 
	pc++;
	index = currentFrame.method.attributes[0].code[pc];
	currentFrame.operandStack.push(currentFrame.localVariables[index])
};

opc[26] = function iload_0() { 
	currentFrame.operandStack.push(currentFrame.localVariables[0]); }
opc[27] = function iload_1() { 
	currentFrame.operandStack.push(currentFrame.localVariables[1]); }
opc[28] = function iload_2() { 
	currentFrame.operandStack.push(currentFrame.localVariables[2]); }
opc[29] = function iload_3() { 
	currentFrame.operandStack.push(currentFrame.localVariables[3]); }
opc[30] = function lload_0() { 
	currentFrame.operandStack.push(currentFrame.localVariables[0]); }
opc[31] = function lload_1() { 
	currentFrame.operandStack.push(currentFrame.localVariables[1]); }
opc[32] = function lload_2() { 
	currentFrame.operandStack.push(currentFrame.localVariables[2]); }
opc[33] = function lload_3() { 
	currentFrame.operandStack.push(currentFrame.localVariables[3]); }
opc[34] = function fload_0() { 
	currentFrame.operandStack.push(currentFrame.localVariables[0]); }
opc[35] = function fload_1() { 
	currentFrame.operandStack.push(currentFrame.localVariables[1]); }
opc[36] = function fload_2() { 
	currentFrame.operandStack.push(currentFrame.localVariables[2]); }
opc[37] = function fload_3() { 
	currentFrame.operandStack.push(currentFrame.localVariables[3]); }
opc[38] = function dload_0() { 
	currentFrame.operandStack.push(currentFrame.localVariables[0]); }
opc[39] = function dload_1() { 
	currentFrame.operandStack.push(currentFrame.localVariables[1]); }
opc[40] = function dload_2() { 
	currentFrame.operandStack.push(currentFrame.localVariables[2]); }
opc[41] = function dload_3() { 
	currentFrame.operandStack.push(currentFrame.localVariables[3]); }
opc[42] = function aload_0() { 
	currentFrame.operandStack.push(currentFrame.localVariables[0]); }
opc[43] = function aload_1() { 
	currentFrame.operandStack.push(currentFrame.localVariables[1]); }
opc[44] = function aload_2() { 
	currentFrame.operandStack.push(currentFrame.localVariables[2]); }
opc[45] = function aload_3() { 
	currentFrame.operandStack.push(currentFrame.localVariables[3]); }

opc[46] = function iaload() { 
	index = currentFrame.operandStack.pop();
	arrayRef = currentFrame.operandStack.pop();
	if(arrayRef == null) {
		//exception, throw null arrayRef
	}
	if(index > arrayRef.size) {
		//exception, throw index > array size
	}
	currentFrame.operandStack.push(arrayRef.array[index]);
}
opc[47] = function laload() { 
	index = currentFrame.operandStack.pop();
	arrayRef = currentFrame.operandStack.pop();
	if(arrayRef == null) {
		//exception, throw null arrayRef
	}
	if(index > arrayRef.size) {
		//exception, throw index > array size
	}
	currentFrame.operandStack.push(arrayRef.array[index]);
}
opc[48] = function faload() { 
	index = currentFrame.operandStack.pop();
	arrayRef = currentFrame.operandStack.pop();
	if(arrayRef == null) {
		//exception, throw null arrayRef
	}
	if(index > arrayRef.size) {
		//exception, throw index > array size
	}
	currentFrame.operandStack.push(arrayRef.array[index]);
}
opc[49] = function daload() { 
	index = currentFrame.operandStack.pop();
	arrayRef = currentFrame.operandStack.pop();
	if(arrayRef == null) {
		//exception, throw null arrayRef
	}
	if(index > arrayRef.size) {
		//exception, throw index > array size
	}
	currentFrame.operandStack.push(arrayRef.array[index]);
}
opc[50] = function aaload() { 
	index = currentFrame.operandStack.pop();
	arrayRef = currentFrame.operandStack.pop();
	if(arrayRef == null) {
		//exception, throw null arrayRef
	}
	if(index > arrayRef.size) {
		//exception, throw index > array size
	}
	currentFrame.operandStack.push(arrayRef.array[index]);
}
opc[51] = function baload() {
	index = currentFrame.operandStack.pop();
	arrayRef = currentFrame.operandStack.pop();
	if(arrayRef == null) {
		//exception, throw null arrayRef
	}
	if(index > arrayRef.size) {
		//exception, throw index > array size
	}
	currentFrame.operandStack.push(arrayRef.array[index]);
}
opc[52] = function caload() {
	index = currentFrame.operandStack.pop();
	arrayRef = currentFrame.operandStack.pop();
	if(arrayRef == null) {
		//exception, throw null arrayRef
	}
	if(index > arrayRef.size) {
		//exception, throw index > array size
	}
	currentFrame.operandStack.push(arrayRef.array[index]);
}
opc[53] = function saload() {
	index = currentFrame.operandStack.pop();
	arrayRef = currentFrame.operandStack.pop();
	if(arrayRef == null) {
		//exception, throw null arrayRef
	}
	if(index > arrayRef.size) {
		//exception, throw index > array size
	}
	currentFrame.operandStack.push(arrayRef.array[index]);
}

opc[54] = function istore() { 
	pc++;
	index = currentFrame.method.attributes[0].code[pc];
	currentFrame.localVariables[index] = currentFrame.operandStack.pop();
};
opc[55] = function lstore() { 
	pc++;
	index = currentFrame.method.attributes[0].code[pc];
	currentFrame.localVariables[index] = currentFrame.operandStack.pop();
};
opc[56] = function dstore() { 
	pc++;
	index = currentFrame.method.attributes[0].code[pc];
	currentFrame.localVariables[index] = currentFrame.operandStack.pop();
};
opc[56] = function fstore() { 
	pc++;
	index = currentFrame.method.attributes[0].code[pc];
	currentFrame.localVariables[index] = currentFrame.operandStack.pop();
};
opc[57] = function astore() { 
	pc++;
	index = currentFrame.method.attributes[0].code[pc];
	currentFrame.localVariables[index] = currentFrame.operandStack.pop();
};

opc[59] = function istore_0() { 
	currentFrame.localVariables[0] = currentFrame.operandStack.pop();};
opc[60] = function istore_1() { 
	currentFrame.localVariables[1] = currentFrame.operandStack.pop();};
opc[61] = function istore_2() { 
	currentFrame.localVariables[2] = currentFrame.operandStack.pop();};
opc[62] = function istore_3() { 
	currentFrame.localVariables[3] = currentFrame.operandStack.pop();};
opc[63] = function lstore_0() { 
	currentFrame.localVariables[0] = currentFrame.operandStack.pop();};
opc[64] = function lstore_1() { 
	currentFrame.localVariables[1] = currentFrame.operandStack.pop();};
opc[65] = function lstore_2() { 
	currentFrame.localVariables[2] = currentFrame.operandStack.pop();};
opc[66] = function lstore_3() { 
	currentFrame.localVariables[3] = currentFrame.operandStack.pop();};
opc[67] = function fstore_0() { 
	currentFrame.localVariables[0] = currentFrame.operandStack.pop();};
opc[68] = function fstore_1() { 
	currentFrame.localVariables[1] = currentFrame.operandStack.pop();};
opc[69] = function fstore_2() { 
	currentFrame.localVariables[2] = currentFrame.operandStack.pop();};
opc[70] = function fstore_3() { 
	currentFrame.localVariables[3] = currentFrame.operandStack.pop();};
opc[71] = function dstore_0() { 
	currentFrame.localVariables[0] = currentFrame.operandStack.pop();};
opc[72] = function dstore_1() { 
	currentFrame.localVariables[1] = currentFrame.operandStack.pop();};
opc[73] = function dstore_2() { 
	currentFrame.localVariables[2] = currentFrame.operandStack.pop();};
opc[74] = function dstore_3() { 
	currentFrame.localVariables[3] = currentFrame.operandStack.pop();};
opc[75] = function astore_0() { 
	currentFrame.localVariables[0] = currentFrame.operandStack.pop();};
opc[76] = function astore_1() { 
	currentFrame.localVariables[1] = currentFrame.operandStack.pop();};
opc[77] = function astore_2() { 
	currentFrame.localVariables[2] = currentFrame.operandStack.pop();};
opc[78] = function astore_3() { 
	currentFrame.localVariables[3] = currentFrame.operandStack.pop();};
opc[79] = function iastore() { 
	value = currentFrame.operandStack.pop();
	index = currentFrame.operandStack.pop();
	arrayRef = currentFrame.operandStack.pop();
	if(arrayRef == null) {
		//exception, throw null arrayRef
	}
	if(index > arrayRef.size) {
		//exception, throw index > array size
	}
	arrayRef[index] = value;
}
opc[80] = function lastore() { 
	value = currentFrame.operandStack.pop();
	index = currentFrame.operandStack.pop();
	arrayRef = currentFrame.operandStack.pop();
	if(arrayRef == null) {
		//exception, throw null arrayRef
	}
	if(index > arrayRef.size) {
		//exception, throw index > array size
	}
	arrayRef[index] = value;
}
opc[81] = function fastore() { 
	value = currentFrame.operandStack.pop();
	index = currentFrame.operandStack.pop();
	arrayRef = currentFrame.operandStack.pop();
	if(arrayRef == null) {
		//exception, throw null arrayRef
	}
	if(index > arrayRef.size) {
		//exception, throw index > array size
	}
	arrayRef[index] = value;
}
opc[82] = function dastore() { 
	value = currentFrame.operandStack.pop();
	index = currentFrame.operandStack.pop();
	arrayRef = currentFrame.operandStack.pop();
	if(arrayRef == null) {
		//exception, throw null arrayRef
	}
	if(index > arrayRef.size) {
		//exception, throw index > array size
	}
	arrayRef[index] = value;
}
opc[83] = function aastore() { 
	value = currentFrame.operandStack.pop();
	index = currentFrame.operandStack.pop();
	arrayRef = currentFrame.operandStack.pop();
	if(arrayRef == null) {
		//exception, throw null arrayRef
	}
	if(index > arrayRef.size) {
		//exception, throw index > array size
	}
	arrayRef[index] = value;
}
opc[84] = function bastore() { 
	value = currentFrame.operandStack.pop();
	index = currentFrame.operandStack.pop();
	arrayRef = currentFrame.operandStack.pop();
	if(arrayRef == null) {
		//exception, throw null arrayRef
	}
	if(index > arrayRef.size) {
		//exception, throw index > array size
	}
	arrayRef[index] = value;
}
opc[85] = function castore() { 
	value = currentFrame.operandStack.pop();
	index = currentFrame.operandStack.pop();
	arrayRef = currentFrame.operandStack.pop();
	if(arrayRef == null) {
		//exception, throw null arrayRef
	}
	if(index > arrayRef.size) {
		//exception, throw index > array size
	}
	arrayRef[index] = value;
}
opc[86] = function sastore() { 
	value = currentFrame.operandStack.pop();
	index = currentFrame.operandStack.pop();
	arrayRef = currentFrame.operandStack.pop();
	if(arrayRef == null) {
		//exception, throw null arrayRef
	}
	if(index > arrayRef.size) {
		//exception, throw index > array size
	}
	arrayRef[index] = value;
}

opc[87] = function pop() { 
	currentFrame.operandStack.pop();
}
opc[88] = function pop2() {
	currentFrame.operandStack.pop();
	currentFrame.operandStack.pop();
}

opc[89] = function dup() {
	value = currentFrame.operandStack.pop();
	currentFrame.operandStack.push(value);
	currentFrame.operandStack.push(value);
}
opc[90] = function dup_x1() {
	value1 = currentFrame.operandStack.pop();
	value2 = currentFrame.operandStack.pop();
	currentFrame.operandStack.push(value1);
	currentFrame.operandStack.push(value2);
	currentFrame.operandStack.push(value1);
}
opc[91] = function dup_x2() {
	value1 = currentFrame.operandStack.pop();
	value2 = currentFrame.operandStack.pop();
	value3 = currentFrame.operandStack.pop();
	currentFrame.operandStack.push(value1);
	currentFrame.operandStack.push(value3);
	currentFrame.operandStack.push(value2);
	currentFrame.operandStack.push(value1);
}
opc[92] = function dup2() {
	value1 = currentFrame.operandStack.pop();
	value2 = currentFrame.operandStack.pop();
	currentFrame.operandStack.push(value2);
	currentFrame.operandStack.push(value1);
	currentFrame.operandStack.push(value2);
	currentFrame.operandStack.push(value1);
}
opc[93] = function dup2_x1() {
	value1 = currentFrame.operandStack.pop();
	value2 = currentFrame.operandStack.pop();
	value3 = currentFrame.operandStack.pop();
	currentFrame.operandStack.push(value2);
	currentFrame.operandStack.push(value1);
	currentFrame.operandStack.push(value3);
	currentFrame.operandStack.push(value2);
	currentFrame.operandStack.push(value1);
}
opc[94] = function dup2_x2() {
	value1 = currentFrame.operandStack.pop();
	value2 = currentFrame.operandStack.pop();
	value3 = currentFrame.operandStack.pop();
	value4 = currentFrame.operandStack.pop();
	currentFrame.operandStack.push(value2);
	currentFrame.operandStack.push(value1);
	currentFrame.operandStack.push(value4);
	currentFrame.operandStack.push(value3);
	currentFrame.operandStack.push(value2);
	currentFrame.operandStack.push(value1);
}

//exception? no Long value??
opc[95] = function swap() {
	value1 = currentFrame.operandStack.pop();
	value2 = currentFrame.operandStack.pop();
	currentFrame.operandStack.push(value2);
	currentFrame.operandStack.push(value1);
}

opc[96] = function iadd() { 
	currentFrame.operandStack.push(currentFrame.operandStack.pop()+currentFrame.operandStack.pop());
};
opc[97] = function ladd() { 
	if(debugMode == 2) {
		output = "ladd: " + currentFrame.operandStack[currentFrame.operandStack.length-2] + "+" + currentFrame.operandStack[currentFrame.operandStack.length-1] + " = ";
	}
	currentFrame.operandStack.push(currentFrame.operandStack.pop()+currentFrame.operandStack.pop());
	if(debugMode == 2) {
		output += currentFrame.operandStack[currentFrame.operandStack.length-1];
		alert(output);
	}
};
opc[98] = function fadd() { 
	currentFrame.operandStack.push(currentFrame.operandStack.pop()+currentFrame.operandStack.pop());
};
opc[99] = function dadd() { 
	currentFrame.operandStack.push(currentFrame.operandStack.pop()+currentFrame.operandStack.pop());
};

opc[100] = function isub() { 
	currentFrame.operandStack.push(-currentFrame.operandStack.pop()+currentFrame.operandStack.pop());
};
opc[101] = function lsub() { 
	currentFrame.operandStack.push(-currentFrame.operandStack.pop()+currentFrame.operandStack.pop());
};
opc[102] = function fsub() { 
	currentFrame.operandStack.push(-currentFrame.operandStack.pop()+currentFrame.operandStack.pop());
};
opc[103] = function dsub() { 
	currentFrame.operandStack.push(-currentFrame.operandStack.pop()+currentFrame.operandStack.pop());
};

opc[104] = function imul() { 
	currentFrame.operandStack.push(currentFrame.operandStack.pop()*currentFrame.operandStack.pop());
};
opc[105] = function lmul() { 
	currentFrame.operandStack.push(currentFrame.operandStack.pop()*currentFrame.operandStack.pop());
};
opc[106] = function dmul() { 
	currentFrame.operandStack.push(currentFrame.operandStack.pop()*currentFrame.operandStack.pop());
};
opc[107] = function fmul() { 
	currentFrame.operandStack.push(currentFrame.operandStack.pop()*currentFrame.operandStack.pop());
};

opc[108] = function idiv() { 
	value2 = currentFrame.operandStack.pop();
	value1 = currentFrame.operandStack.pop();
	currentFrame.operandStack.push(Math.floor(value1/value2));
};
opc[109] = function ldiv() { 
	value2 = currentFrame.operandStack.pop();
	value1 = currentFrame.operandStack.pop();
	currentFrame.operandStack.push(Math.floor(value1/value2));
};
opc[110] = function fdiv() { 
	value2 = currentFrame.operandStack.pop();
	value1 = currentFrame.operandStack.pop();
	currentFrame.operandStack.push(value1/value2);
};
opc[111] = function ddiv() { 
	value2 = currentFrame.operandStack.pop();
	value1 = currentFrame.operandStack.pop();
	currentFrame.operandStack.push(value1/value2);
};

opc[112] = function irem() { 
	value2 = currentFrame.operandStack.pop();
	value1 = currentFrame.operandStack.pop();
	currentFrame.operandStack.push(value1-Math.floor(value1/value2) * value2);
};
opc[113] = function lrem() { 
	value2 = currentFrame.operandStack.pop();
	value1 = currentFrame.operandStack.pop();
	currentFrame.operandStack.push(value1-Math.floor(value1/value2) * value2);
};
//***todo, I do not know how to represent infinity number in JS
//so here I did not include the case where the dividend and dividor wil be infinity number
opc[114] = function frem() { 
	value2 = currentFrame.operandStack.pop();
	value1 = currentFrame.operandStack.pop();
	if(value1 == NaN || value2 == NaN) {
		currentFrame.operandStack.push(NaN);
	} else if(value2 == 0) {
		currentFrame.operandStack.push(NaN);
	} else if(value1 == 0) {
		currentFrame.operandStack.push(0);
	} else {
		if(value1 >= 0) {
			sign = 1;
		} else {
			sign = -1;
		}
		if(value1 < 0) {
			value1 = - value1;
		}
		if(value2 < 0) {
			value22 = -value2;
		}
		currentFrame.operandStack.push(sign*(value1-Math.floor(value1/value2) * value2));
	}
};
opc[115] = function drem() { 
	value2 = currentFrame.operandStack.pop();
	value1 = currentFrame.operandStack.pop();
	if(value1 == NaN || value2 == NaN) {
		currentFrame.operandStack.push(NaN);
	} else if(value2 == 0) {
		currentFrame.operandStack.push(NaN);
	} else if(value1 == 0) {
		currentFrame.operandStack.push(0);
	} else {
		if(value1 >= 0) {
			sign = 1;
		} else {
			sign = -1;
		}
		if(value1 < 0) {
			value1 = - value1;
		}
		if(value2 < 0) {
			value22 = -value2;
		}
		currentFrame.operandStack.push(sign*(value1-Math.floor(value1/value2) * value2));
	}
};
opc[116] = function ineg() {
	currentFrame.operandStack.push(-currentFrame.operandStack.pop());
}
opc[117] = function lneg() {
	currentFrame.operandStack.push(-currentFrame.operandStack.pop());
}
opc[118] = function fneg() {
	currentFrame.operandStack.push(-currentFrame.operandStack.pop());
}
opc[119] = function dneg() {
	currentFrame.operandStack.push(-currentFrame.operandStack.pop());
}

opc[120] = function ishl() {
	value2 = currentFrame.operandStack.pop();
	value1 = currentFrame.operandStack.pop();
	s = value2 & 31; //get the lowest five bits
	currentFrame.operandStack.push(value1 <<= s);
}
opc[121] = function lshl() {
	value2 = currentFrame.operandStack.pop();
	value1 = currentFrame.operandStack.pop();
	s = value2 & 63; //get the lowest six bits
	currentFrame.operandStack.push(value1 <<= s);
}
opc[122] = function ishr() {
	value2 = currentFrame.operandStack.pop();
	value1 = currentFrame.operandStack.pop();
	s = value2 & 31; //get the lowest five bits
	currentFrame.operandStack.push(value1 >>= s);
}
opc[123] = function lshr() {
	value2 = currentFrame.operandStack.pop();
	value1 = currentFrame.operandStack.pop();
	s = value2 & 63; //get the lowest six bits
	currentFrame.operandStack.push(value1 >>= s);
}
opc[124] = function iushr() {
	value2 = currentFrame.operandStack.pop();
	value1 = currentFrame.operandStack.pop();
	s = value2 & 0x1f; //get the lowest five bits
	if(value >= 0) {
		value1 >>= s;
	} else {
		value1 = (value1 >> s) + (2 << ~s);
	}
	currentFrame.operandStack.push(value1);
}
opc[125] = function lushr() {
	value2 = currentFrame.operandStack.pop();
	value1 = currentFrame.operandStack.pop();
	s = value2 & 0x3f; //get the lowest five bits
	if(value >= 0) {
		value1 >>= s;
	} else {
		value1 = (value1 >> s) + (2 << ~s);
	}
	currentFrame.operandStack.push(value1);
}
opc[126] = function iand() {
	currentFrame.operandStack.push(currentFrame.operandStack.pop()&currentFrame.operandStack.pop());
}
opc[127] = function land() {
	currentFrame.operandStack.push(currentFrame.operandStack.pop()&currentFrame.operandStack.pop());
}
opc[128] = function ior() {
	currentFrame.operandStack.push(currentFrame.operandStack.pop()| currentFrame.operandStack.pop());
}
opc[129] = function lor() {
	currentFrame.operandStack.push(currentFrame.operandStack.pop()| currentFrame.operandStack.pop());
}
opc[130] = function ixor() {
	currentFrame.operandStack.push(currentFrame.operandStack.pop() ^  currentFrame.operandStack.pop());
}
opc[131] = function lxor() {
	currentFrame.operandStack.push(currentFrame.operandStack.pop() ^  currentFrame.operandStack.pop());
}
opc[132] = function iinc() {
	pc++;
	index = currentFrame.method.attributes[0].code[pc];
	pc++;
	constValue = currentFrame.method.attributes[0].code[pc];
	currentFrame.localVariables[index] += constValue;
}
opc[133] = function i2l() {
	//do nothing in this program, since this program did not discrete these two kinds of numbers
}
opc[134] = function i2f() {
	//do nothing in this program, since this program did not discrete these two kinds of numbers
}
opc[135] = function i2d() {
	//do nothing in this program, since this program did not discrete these two kinds of numbers
}
opc[136] = function l2i() {
	//do nothing in this program, since this program did not discrete these two kinds of numbers
}
opc[137] = function l2f() {
	//do nothing in this program, since this program did not discrete these two kinds of numbers
}
opc[138] = function l2d() {
	//do nothing in this program, since this program did not discrete these two kinds of numbers
}
opc[139] = function f2i() {
	num = currentFrame.operandStack.pop();
	if(num == NaN) {
		currentFrame.operandStack.push(0);
	} else {
		currentFrame.operandStack.push(Math.round(num));
	}
}
opc[140] = function f2l() {
	num = currentFrame.operandStack.pop();
	if(num == NaN) {
		currentFrame.operandStack.push(0);
	} else {
		currentFrame.operandStack.push(Math.round(num));
	}
}
opc[141] = function f2d() {
	//do nothing in this program, since this program did not discrete these two kinds of numbers
}
opc[142] = function d2i() {
	num = currentFrame.operandStack.pop();
	if(num == NaN) {
		currentFrame.operandStack.push(0);
	} else {
		currentFrame.operandStack.push(Math.round(num));
	}
}
opc[143] = function d2l() {
	num = currentFrame.operandStack.pop();
	if(num == NaN) {
		currentFrame.operandStack.push(0);
	} else {
		currentFrame.operandStack.push(Math.round(num));
	}
}
opc[144] = function d2f() {
	//do nothing in this program, since this program did not discrete these two kinds of numbers
}
//what is byte?***todo
opc[145] = function i2b() {
	value = currentFrame.operandStack.pop();
	byteValue = value & 255;
	currentFrame.operandStack.push(byteValue);
}
//***todo, how to change int to char???
opc[146] = function i2c() {
	value = currentFrame.operandStack.pop();
	charValue = value & 65535;
	currentFrame.operandStack.push(charValue);
}
//***todo, how to change int to short
opc[147] = function i2s() {
	value = currentFrame.operandStack.pop();
	shortValue = value & 65535;
	currentFrame.operandStack.push(shortValue);
}

opc[148] = function lcmp() {
	value2 = currentFrame.operandStack.pop();
	value1 = currentFrame.operandStack.pop();
	if(value1 > value2) {
		currentFrame.operandStack.push(1);
	} else if(value1 == value2) {
		currentFrame.operandStack.push(0);
	} else {
		currentFrame.operandStack.push(-1);
	}
}
//***todo, value set conversion
opc[149] = function fcmpl() {
	value2 = currentFrame.operandStack.pop();
	value1 = currentFrame.operandStack.pop();
	if(value1 > value2) {;
		currentFrame.operandStack.push(1);
	} else if(value1 == value2) {
		currentFrame.operandStack.push(0);
	} else if(value1 < value2){
		currentFrame.operandStack.push(-1);
	} else { //it is NaN in the stack
		currentFrame.operandStack.push(1);
	}
}
//***todo
opc[150] = function fcmpg() {
	value2 = currentFrame.operandStack.pop();
	value1 = currentFrame.operandStack.pop();
	if(value1 > value2) {
		currentFrame.operandStack.push(1);
	} else if(value1 == value2) {
		currentFrame.operandStack.push(0);
	} else if(value1 < value2){
		currentFrame.operandStack.push(-1);
	} else { //it is NaN in the stack
		currentFrame.operandStack.push(-1);
	}
}
//***todo, value set conversion
opc[151] = function dcmpl() {
	value2 = currentFrame.operandStack.pop();
	value1 = currentFrame.operandStack.pop();
	if(value1 > value2) {;
		currentFrame.operandStack.push(1);
	} else if(value1 == value2) {
		currentFrame.operandStack.push(0);
	} else if(value1 < value2){
		currentFrame.operandStack.push(-1);
	} else { //it is NaN in the stack
		currentFrame.operandStack.push(1);
	}
}
//***todo
opc[152] = function dcmpg() {
	value2 = currentFrame.operandStack.pop();
	value1 = currentFrame.operandStack.pop();
	if(value1 > value2) {
		currentFrame.operandStack.push(1);
	} else if(value1 == value2) {
		currentFrame.operandStack.push(0);
	} else if(value1 < value2){
		currentFrame.operandStack.push(-1);
	} else { //it is NaN in the stack
		currentFrame.operandStack.push(-1);
	}
}

//***todo, perhaps wrong with the exact transfer number, the following also be included
opc[153] = function ifeq() { 
	pc++;
	branchbyte1 = currentFrame.method.attributes[0].code[pc];
	pc++;
	branchbyte2 = currentFrame.method.attributes[0].code[pc];
	branchbyte = branchbyte1 << 8 | branchbyte2;
	value = currentFrame.operandStack.pop();
	if(value == 0) {
		pc = pc + branchbyte;
	}
};
opc[154] = function ifne() { 
	pc++;
	branchbyte1 = currentFrame.method.attributes[0].code[pc];
	pc++;
	branchbyte2 = currentFrame.method.attributes[0].code[pc];
	branchbyte = branchbyte1 << 8 | branchbyte2;
	value = currentFrame.operandStack.pop();
	if(value != 0) {
		pc = pc + branchbyte;
	}
 };
opc[155] = function iflt() { 
	pc++;
	branchbyte1 = currentFrame.method.attributes[0].code[pc];
	pc++;
	branchbyte2 = currentFrame.method.attributes[0].code[pc];
	branchbyte = branchbyte1 << 8 | branchbyte2;
	value = currentFrame.operandStack.pop();
	if(value < 0) {
		pc = pc + branchbyte;
	}
};
opc[156] = function ifge() { 
	pc++;
	branchbyte1 = currentFrame.method.attributes[0].code[pc];
	pc++;
	branchbyte2 = currentFrame.method.attributes[0].code[pc];
	branchbyte = branchbyte1 << 8 | branchbyte2;
	value = currentFrame.operandStack.pop();
	if(value >= 0) {
		pc = pc + branchbyte;
	}
};
opc[157] = function ifgt() { 
	pc++;
	branchbyte1 = currentFrame.method.attributes[0].code[pc];
	pc++;
	branchbyte2 = currentFrame.method.attributes[0].code[pc];
	branchbyte = branchbyte1 << 8 | branchbyte2;
	value = currentFrame.operandStack.pop();
	if(value > 0) {
		pc = pc + branchbyte;
	}
};
opc[158] = function ifle() {  
	pc++;
	branchbyte1 = currentFrame.method.attributes[0].code[pc];
	pc++;
	branchbyte2 = currentFrame.method.attributes[0].code[pc];
	branchbyte = branchbyte1 << 8 | branchbyte2;
	value = currentFrame.operandStack.pop();
	if(value <= 0) {
		pc = pc + branchbyte;
	}
};

opc[159] = function if_icmpeq() { 
	pc++;
	branchbyte1 = currentFrame.method.attributes[0].code[pc];
	pc++;
	branchbyte2 = currentFrame.method.attributes[0].code[pc];
	branchbyte = branchbyte1 << 8 | branchbyte2;
	value2 = currentFrame.operandStack.pop();
	value1 = currentFrame.operandStack.pop();
	if(value1 == value2) {
		pc = pc + branchbyte;
	}
};
opc[160] = function if_icmpne() { 
	pc++;
	branchbyte1 = currentFrame.method.attributes[0].code[pc];
	pc++;
	branchbyte2 = currentFrame.method.attributes[0].code[pc];
	branchbyte = branchbyte1 << 8 | branchbyte2;
	value2 = currentFrame.operandStack.pop();
	value1 = currentFrame.operandStack.pop();
	if(value1 != value2) {
		pc = pc + branchbyte;
	}
};
opc[161] = function if_icmplt() { 
	pc++;
	branchbyte1 = currentFrame.method.attributes[0].code[pc];
	pc++;
	branchbyte2 = currentFrame.method.attributes[0].code[pc];
	branchbyte = branchbyte1 << 8 | branchbyte2;
	value2 = currentFrame.operandStack.pop();
	value1 = currentFrame.operandStack.pop();
	if(value1 < value2) {
		pc = pc + branchbyte;
	}
};
opc[162] = function if_icmpge() { 
	pc++;
	branchbyte1 = currentFrame.method.attributes[0].code[pc];
	pc++;
	branchbyte2 = currentFrame.method.attributes[0].code[pc];
	branchbyte = branchbyte1 << 8 | branchbyte2;
	value2 = currentFrame.operandStack.pop();
	value1 = currentFrame.operandStack.pop();
	if(value1 >= value2) {
		pc = pc + branchbyte;
	}
};
opc[163] = function if_icmpgt() { 
	pc++;
	branchbyte1 = currentFrame.method.attributes[0].code[pc];
	pc++;
	branchbyte2 = currentFrame.method.attributes[0].code[pc];
	branchbyte = branchbyte1 << 8 | branchbyte2;
	value2 = currentFrame.operandStack.pop();
	value1 = currentFrame.operandStack.pop();
	if(value1 > value2) {
		pc = pc + branchbyte;
	}
};
opc[164] = function if_icmple() { 
	pc++;
	branchbyte1 = currentFrame.method.attributes[0].code[pc];
	pc++;
	branchbyte2 = currentFrame.method.attributes[0].code[pc];
	branchbyte = branchbyte1 << 8 | branchbyte2;
	value2 = currentFrame.operandStack.pop();
	value1 = currentFrame.operandStack.pop();
	if(value1 <= value2) {
		pc = pc + branchbyte;
	}
};
opc[165] = function if_acmpeq() { 
	pc++;
	branchbyte1 = currentFrame.method.attributes[0].code[pc];
	pc++;
	branchbyte2 = currentFrame.method.attributes[0].code[pc];
	branchbyte = branchbyte1 << 8 | branchbyte2;
	value2 = currentFrame.operandStack.pop();
	value1 = currentFrame.operandStack.pop();
	if(value1 == value2) {
		pc = pc + branchbyte;
	}
};
opc[166] = function if_acmpne() { 
	pc++;
	branchbyte1 = currentFrame.method.attributes[0].code[pc];
	pc++;
	branchbyte2 = currentFrame.method.attributes[0].code[pc];
	branchbyte = branchbyte1 << 8 | branchbyte2;
	value2 = currentFrame.operandStack.pop();
	value1 = currentFrame.operandStack.pop();
	if(value1 != value2) {
		pc = pc + branchbyte;
	}
};

//***todo, perhaps be wrong
opc[167] = function goto_n() { //goto
	pc++;
	branchbyte1 = currentFrame.method.attributes[0].code[pc];
	pc++;
	branchbyte2 = currentFrame.method.attributes[0].code[pc];
	branchbyte = branchbyte1 << 8 | branchbyte2;

	pc = pc + branchbyte;
}

//*****todo unfinished yet, do not know how to implement it
opc[168] = function jsr() { }
opc[169] = function ret() { }

//***todo, unfinished yet
opc[170] = function tableswitch() { 

}
//***todo, unfinished yet
opc[171] = function lookupswitch() { 

}

opc[172] = function ireturn() { 
	if(debugMode == 2) 
		alert("ireturn");
	if(callStack.length >= 2) {
		callStack[callStack.length-2].operandStack.push(currentFrame.operandStack.pop());
		callStack.pop();
		currentFrame = callStack[callStack.length-1];
		pc = currentFrame.currentPc;
		this.codelength = currentFrame.method.attributes[0].code_length;
	} else {
		alert("callStack length less than 2, 172");
		//returnValue = null;
	}
};
opc[173] = function lreturn() { 
	if(callStack.length >= 2) {
		callStack[callStack.length-2].operandStack.push(currentFrame.operandStack.pop());
		callStack.pop();
		currentFrame = callStack[callStack.length-1];
		pc = currentFrame.currentPc;
		this.codelength = currentFrame.method.attributes[0].code_length;
	} else {
		alert("callStack length less than 2, 173");
		//returnValue = null;
	}
};
opc[174] = function freturn() { 
	if(callStack.length >= 2) {
		callStack[callStack.length-2].operandStack.push(currentFrame.operandStack.pop());
		callStack.pop();
		currentFrame = callStack[callStack.length-1];
		pc = currentFrame.currentPc;
		this.codelength = currentFrame.method.attributes[0].code_length;
	} else {
		alert("callStack length less than 2, 174");
		//returnValue = null;
	}
};
opc[175] = function dreturn() { 
	if(callStack.length >= 2) {
		callStack[callStack.length-2].operandStack.push(currentFrame.operandStack.pop());
		callStack.pop();
		currentFrame = callStack[callStack.length-1];
		pc = currentFrame.currentPc;
		this.codelength = currentFrame.method.attributes[0].code_length;
	} else {
		alert("callStack length less than 2, 175");
		//returnValue = null;
	}
};
opc[176] = function dreturn() { 
	if(callStack.length >= 2) {
		callStack[callStack.length-2].operandStack.push(currentFrame.operandStack.pop());
		callStack.pop();
		currentFrame = callStack[callStack.length-1];
		pc = currentFrame.currentPc;
		this.codelength = currentFrame.method.attributes[0].code_length;
	} else {
		alert("callStack length less than 2, 176");
		//returnValue = null;
	}
};

opc[177] = function returnNull() { 
	if(callStack.length >= 2) {
		callStack.pop();
		currentFrame = callStack[callStack.length-1];
		pc = currentFrame.currentPc;
	} else {
		alert("callStack length less than 2, 177");
	//alert("return");
	}
};

opc[178] = function getstatic() {
	if(debugMode == 1) 
		alert("getstatic");
	pc++;
	indexbyte1 = currentFrame.method.attributes[0].code[pc];
	pc++;
	indexbyte2 = currentFrame.method.attributes[0].code[pc];
	index = (indexbyte1 << 8) | indexbyte2;

	if(mainclass.constant_pool[index].tag == 20) { //this number means it has been visited before
		currentFrame.operandStack.push(mainclass.constant_pool[index].content);
	} else {

	}
};

opc[179] = function putstatic() { 
	if(debugMode == 1) 
		alert("putstatic");
	pc++;
	indexbyte1 = currentFrame.method.attributes[0].code[pc];
	pc++;
	indexbyte2 = currentFrame.method.attributes[0].code[pc];
	index = (indexbyte1 << 8) | indexbyte2;
	mainclass.constant_pool[index].tag = 20; //this number means it has been analyzed
	mainclass.constant_pool[index].content = currentFrame.operandStack.pop();
};

//***unfinished yet
opc[180] = function getfield() { 
};
opc[181] = function putfield() { 
};
//fake native methods, just for demo
opc[182] = function invokevirtual() { 
	if(debugMode == 1)
		alert("invokevirtual");
	pc++;
	indexbyte1 = currentFrame.method.attributes[0].code[pc];
	pc++;
	indexbyte2 = currentFrame.method.attributes[0].code[pc];
	index = (indexbyte1 << 8) | indexbyte2;
	
	nameTypeIndex = mainclass.constant_pool[index].name_and_type_index;
	nameIndex = mainclass.constant_pool[nameTypeIndex].name_index;
	typeIndex = mainclass.constant_pool[nameTypeIndex].descriptor_index;
	if(getStringFromConstantId(nameIndex) == "println") {
		alert("print: "+currentFrame.operandStack.pop());
	}

};

//***unfinished yet
opc[183] = function invokespecial() { 
};


opc[184] = function invokestatic() { 
	if(debugMode == 1)
		alert("invokestatic");
	pc++;
	indexbyte1 = currentFrame.method.attributes[0].code[pc];
	pc++;
	indexbyte2 = currentFrame.method.attributes[0].code[pc];
	index = (indexbyte1 << 8) | indexbyte2;
	currentFrame.currentPc = pc; //memorize the next pc position
	if(debugMode == 1)
		alert("currentPc:"+currentFrame.currentPc);

	nextFrame = new callFrame();

	//ignore the class part, we have only mainclass here.
	nameTypeIndex = mainclass.constant_pool[index].name_and_type_index;
	nameIndex = mainclass.constant_pool[nameTypeIndex].name_index;
	descriptor_index = mainclass.constant_pool[nameTypeIndex].descriptor_index;
	if(debugMode == 1)
		alert("method: " + descriptor_index);
	nextMethod = findMethodByNameIndex(nameIndex);
	nextFrame.method = nextMethod;
	inputNum = findDescriptorInputNum(descriptor_index);
	//alert("inputNum: " + inputNum);
	for(i = inputNum-1; i >= 0; i--) {
		nextFrame.localVariables[i] = currentFrame.operandStack.pop();
	}
	
	callStack.push(nextFrame);
	currentFrame = callStack[callStack.length-1];
	//alert("currentFrame LocalVariables: " + currentFrame.localVariables);
	//alert("second pc: " +callStack[callStack.length-2].currentPc);
	currentFrame.execute();

};

//***unfinished yet
opc[185] = function invokeinterface() { 
};
opc[187] = function newobj() { 
};

opc[188] = function newarray() {
	size = currentFrame.operandStack.pop();
	if(size < 0) {
		//throw: negative array size;
	}
	pc++;
	var type;
	typeNum = currentFrame.method.attributes[0].code[pc];
	switch(typeNum) {
		case 4: type = "BOOLEAN"; break;
		case 5: type = "CHAR"; break;
		case 6: type = "FLOAT"; break;
		case 7: type = "DOUBLE"; break;
		case 8: type = "BYTE"; break;
		case 9: type = "SHORT"; break;
		case 10: type = "INT"; break;
		case 11: type = "LONG"; break;
		default: alert("not existed type");
	}
	//create a new array
	//****not sure about this method
	var arrayObject = new ArrayObject(type,size);
	currentFrame.operandStack.push(arrayObject);
}

//***unfinished yet
opc[189] = function anewarray() {}

opc[190] = function arraylength() {
	arrayRef = currentFrame.operandStack.pop();
	if(arrayRef == null) {
		//exception, throw NullPointerException	
	} else {
		currentFrame.operandStack.push(arrayRef.size);
	}
}

//***unfinished yet
opc[191] = function athrow() {

}

//***unfinished yet
opc[192] = function checkcast() {

}
opc[193] = function instanceof_op() {;};
opc[194] = function monitorenter() {;};
opc[195] = function monitorexit() {;};
opc[196] = function wide() {;};
opc[197] = function multianewarray() {;};

opc[198] = function ifnull() { 
	pc++;
	branchbyte1 = currentFrame.method.attributes[0].code[pc];
	pc++;
	branchbyte2 = currentFrame.method.attributes[0].code[pc];
	branchbyte = branchbyte1 << 8 | branchbyte2;
	value = currentFrame.operandStack.pop();
	if(value == null) {
		pc = pc + branchbyte;
	}
};
opc[199] = function ifnonnull() { 
	pc++;
	branchbyte1 = currentFrame.method.attributes[0].code[pc];
	pc++;
	branchbyte2 = currentFrame.method.attributes[0].code[pc];
	branchbyte = branchbyte1 << 8 | branchbyte2;
	value = currentFrame.operandStack.pop();
	if(value != null) {
		pc = pc + branchbyte;
	}
};

opc[200] = function goto_w() {
	pc++;
	branchbyte1 = currentFrame.method.attributes[0].code[pc];
	pc++;
	branchbyte2 = currentFrame.method.attributes[0].code[pc];
	pc++;
	branchbyte3 = currentFrame.method.attributes[0].code[pc];
	pc++;
	branchbyte4 = currentFrame.method.attributes[0].code[pc];
	branchbyte = (branchbyte1 << 24) | (branchbyte2 << 16) | (branchbyte3 << 8) | branchbyte4;

	pc = pc + branchbyte;
};

opc[201] = function jsr_w() {
};

//get the number of descriptor types, like (IIII)I
findDescriptorInputNum = function(dIndex) {
	descriptorString = mainclass.constant_pool[dIndex].bytes;
	//alert("descriptorString: " + descriptorString);
	num = 0;
	for(i = 1; i < descriptorString.length; i++) {
		if(descriptorString[i] != 41) { //41 == ')'
			num++;
		} else {
			return num;
		}
	}
}

//get method name by method name index
findMethodByNameIndex = function(nameIndex) {
	//alert("in findMethodByNameIndex");
	for(i in mainclass.methods) {
		//alert("methods: "+i);
		if(mainclass.methods[i].name_index == nameIndex) {
			//alert("find "+name);
			//execute the found method, construct a new frame, and push it into the callStack
			return mainclass.methods[i];
		}
	}
}

//get the strings from constant pool
getStringFromConstantId = function(id) {
	stringValue = "";
	for(everyChar in mainclass.constant_pool[id].bytes) {
		charValue = String.fromCharCode(mainclass.constant_pool[id].bytes[everyChar]);
		stringValue += charValue;
	}
		//alert(stringValue);
	return stringValue;
}

